//-----------------------------------------------------------------------
// <copyright file="RemoveComponent.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// </copyright>
// <author>Andy Reeves</author>
// <email>andyr</email>
// <date>2004-03-23</date>
// <summary>Removes a Component from the specified ComponentServices Application.</summary>
//-----------------------------------------------------------------------

namespace Microsoft.Sdc.Tasks.ComponentServices.Application
{
    using System;
    using System.IO;
    using System.Globalization;
    using Microsoft.Win32;
    using Microsoft.Sdc.Tasks.Configuration.ComponentServices;
    using Microsoft.Build.Framework;
    using Microsoft.Sdc.Tasks.Configuration;

    /// <summary>
    /// Removes a specified Component from the specified ComponentServices Application.
    /// </summary>
    /// <remarks>
    /// <code><![CDATA[<ComponentServices.Application.RemoveComponent Path="path" ApplicationName="applicationName" ConstructorString="constructorString" Runtime="runtime" />]]></code>
    /// <para>where:</para>
    /// <para><i>path (Required)</i></para>
    /// <para>The path to the component DLL to be removed from the application.</para>
    /// <para><i>applicationName</i></para>
    /// <para>The name of the COM+ application which the component will be removed from. If there are multiple applications with the same name, the component will be removed from all of them.</para>
    /// <para><i>runtime</i></para>
    /// <para>Decimal value for version of runtime targeted. Defaults to "2.0"</para>
    /// </remarks>
    /// <example>
    /// <code><![CDATA[
    /// <Project>
    ///     <Target Name="Test" >
    ///         <ComponentServices.Application.RemoveComponent
    ///             Path="C:\Soutions\MyNamespace.MyAssembly.dll"
    ///             ApplicationName="MyApplicationName"
    ///             Runtime="1.1" />
    ///     </Target>
    /// </Project>
    /// ]]></code>    
    /// </example>
    public class RemoveComponent : TaskBase
    {
        private string path;
        private string runtime = String.Empty;
        private string applicationName;

        /// <summary>
        /// Gets or sets the path to the component DLL to be removed from the application.
        /// </summary>
        /// <value>Valid path to the component DLL</value>
        [Required]
        public string Path
        {
            get { return this.path; }
            set { this.path = value; }
        }

        /// <summary>
        /// Gets or sets the name of the COM+ application which the component will be removed from. 
        /// </summary>
        /// <value>The application name that the specified component will be removed from. If there are multiple applications with the same name, the component will be removed from all of them.</value>
        public string ApplicationName
        {
            get { return this.applicationName; }
            set { this.applicationName = value; }
        }

        /// <summary>
        /// Gets or sets the Decimal value for version of runtime targeted.
        /// </summary>
        /// <value>The version of the .NET runtime targeted. Defaults to "1.0".</value>
        public string Runtime
        {
            get { return this.runtime; }
            set { this.runtime = value; }
        }

        /// <summary>
        /// Performs the action of this task.
        /// </summary>
        protected override void InternalExecute()
        {
            #region Execute code

            FileInfo fi = new FileInfo(this.path);
            if (fi.Exists == false)
            {
                Log.LogError(string.Format("Path not found: {0}: ", this.Path));
                return;
            }

            Log.LogMessageFromResources("ComponentServices.RemovingComponent", fi.Name);

            // Detect if its a .NET assembly or not
            if (Utilities.IsValidAssemblyFile(fi.FullName))
            {
                string version = "";
                if (this.Runtime.Length == 0 || this.Runtime == "2.0")
                {
                    version = "v2.0.50727";
                }
                else if (this.Runtime == "1.1")
                {
                    version = "v1.1.4322";
                }
                else if (this.Runtime == "1.0")
                {
                    version = "v1.0.3705";
                }

                RegistryKey runtimeKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\.NETFramework");
                string pathToFramework =
                    Convert.ToString(runtimeKey.GetValue("InstallRoot"), CultureInfo.InvariantCulture);
                runtimeKey.Close();

                ShellExecute shellExecute = new ShellExecute();
                shellExecute.Filename =
                    System.IO.Path.Combine(System.IO.Path.Combine(pathToFramework, version), "regsvcs.exe");
                string args;
                args = String.Format(CultureInfo.InvariantCulture, @"/quiet /u ""{0}""", this.path);
                shellExecute.Arguments = args;
                int exitcode = shellExecute.Execute();

                if (exitcode != 0)
                {
                    Log.LogError("Shell execute failed: " + shellExecute.StandardOutput);
                }
            }
            else
            {
                Application.RemoveComponent(this.path, this.applicationName);
            }

            #endregion
        }
    }
}